{-# LANGUAGE NoMonomorphismRestriction #-}
import Control.Monad.Cont
import Data.Maybe
import Data.List 

data Event m a = Closed {juice :: a} | Open {juice :: a,  pends :: Depends m a,  match :: Match m a}

instance Eq a => Eq (Event m a) where
	x == y 	= juice x == juice y 

instance Show a => Show (Event m a) where
	show (Closed a) 	= "Closed " ++ show a
	show (Open a _ _) 	= "Open " ++ show a

type Match m a = Event m a -> Bool

type Depends m a = [Event m a] -> m (Maybe (Event m a))

dependence :: Monad m => [Event m a] -> [Depends m a]
dependence = map fst . foldr f [] where
	f e s = case e of 	Closed _ -> sn
				Open _ p m -> (p,m):sn 
		where sn = filter (\(_,m) -> not $ m e) s  

events :: (Eq a, Monad m) => [Event m a] -> m [Event m a]
events es = catMaybes `liftM` (mapM ($ es) $ dependence es)

stable :: (Eq a, Monad m) => [Event m a] -> m [Event m a]		
stable = r where 
	r es = do 	ns <- events es
			if not $ null ns then  r (ns ++ es)  
				else return es

e = Closed "paolo"
e1 = Open "sara" (\x -> return $ if Closed "paolo" `elem` x then Just  (Closed "luca") else Nothing)  (==Closed "luca")

